#include<fcntl.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<errno.h>
#include<sys/socket.h>
#include<string.h>
#include<stdlib.h>
#include<sys/epoll.h>
#include<unistd.h>
#include <netinet/in.h> 
int main(int argc,char* argv[])
{
	if(argc<2)
	{
		printf("缺少第二个参数(端口信息)");
		return -1;
	}
	
	int port=atoi(argv[1]);

	int sockfd,clientfd;
	sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(sockfd<0)
	{
		printf("创建socket失败");
		return -2;
	}	

	struct sockaddr_in serv_addr;

	memset(&serv_addr,0,sizeof(serv_addr));
	serv_addr.sin_family=AF_INET;
	serv_addr.sin_port=htons(port);
	serv_addr.sin_addr.s_addr=INADDR_ANY;

	if(bind(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr))<0)
	{
		printf("绑定端口失败!");
		return -3;
	}

	if(listen(sockfd,10)<0)
	{
		printf("监听端口失败！");
		return -4;
	}

	int nready;
	int epfd=epoll_create(256);
	if(epfd<0)
	{
		printf("创建epoll失败");
		return -1;
	}	

	struct epoll_event ev,events[1024]={0};
	memset(&ev,0,sizeof(struct epoll_event));
	ev.events=EPOLLIN;
	ev.data.fd=sockfd;
	epoll_ctl(epfd,EPOLL_CTL_ADD,sockfd,&ev);

	
	while(1)
	{
	nready=epoll_wait(epfd,events,1024,-1);
	if(nready<0)
	{
		break;
	}

	int i;
	for(i=0;i<nready;++i)
	{
	if(events[i].data.fd==sockfd)
	{
		struct sockaddr_in client_addr;
		memset(&client_addr,0,sizeof(struct sockaddr_in));
		socklen_t len=sizeof(client_addr); 
		clientfd=accept(sockfd,(struct sockaddr*)&client_addr,&len);

		if(clientfd<=0)
		{
			continue;
		}

		char str[INET_ADDRSTRLEN]={0};

		printf("客户端地址为%s,端口号为:%d\n",inet_ntop(AF_INET,&client_addr.sin_addr,str,sizeof(str)),
		ntohs(client_addr.sin_port));

		ev.events=EPOLLIN;
		ev.data.fd=clientfd;
		epoll_ctl(epfd,EPOLL_CTL_ADD,clientfd,&ev);
	}
	else 
	{
		char buffer[1024]={0};

		//非阻塞情况下recv如果没有数据可读会返回-1,其他情况比如网络异常会将errno设置为相应的值
		int n=recv(clientfd,buffer,5,0);
		if(n<0)
		{
			if(errno==EAGAIN||errno==EWOULDBLOCK)
			{
		printf("没有数据可读");
			}else
			{

			}
			close(clientfd);
			ev.events=EPOLLIN;
			ev.data.fd=clientfd;
			epoll_ctl(epfd,EPOLL_CTL_DEL,clientfd,&ev);
		}
		else if(n==0)
		{
		//客户端断开与服务器端的连接,recv会返回0
		//客户端向服务器端发送FIN包,然后服务器端回了确认消息，如果服务器端不向客户端主动发送FIN包，那么服务器端就会存在
		//time_wait状态等待一段时间，因为服务器可能要处理一些其他的事务，处理完之后，服务器端向客户端发送FIN包，也就是服务
		//器端主动close(clienfd);之后客户端收到了服务端的FIN包，并确认后，连接才正式关闭

		//这里可能会处理一些其他的业务逻辑，处理业务逻辑所需的时间也就是time_wait的时间

			printf("断开连接...\n");
			close(clientfd);
			ev.events=EPOLLIN;
			ev.data.fd=clientfd;
			epoll_ctl(epfd,EPOLL_CTL_DEL,clientfd,&ev);

		}
		else
		{
			printf("recv=%s,收到的字节数为=%d\n",buffer,n);

		}



	}






	}





	}






	return 0;
}